package web.controller.sys;

import com.github.pagehelper.PageInfo;
import framework.storage.FileStorage;
import framework.utils.CharsetUtil;
import framework.vo.ResultInfo;
import framework.vo.ResultList;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import system.entity.SysTaskDetail;
import system.entity.SysTaskLog;
import system.service.sys.SysTaskDetailService;
import system.service.sys.SysTaskLogService;
import system.task.utils.TaskUtil;

import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.List;

@RestController
@RequestMapping("/sys/task/log")
@Api(tags = "任务计划")
public class SysTaskLogController {
    @Autowired
    private SysTaskLogService sysTaskLogService;
    @Autowired
    private SysTaskDetailService sysTaskDetailService;
    @Autowired
    private FileStorage fileStorage;

    @ApiOperation("添加任务执行记录")
    @PostMapping("/add")
    public ResultInfo<String> add(@ModelAttribute SysTaskLog param) {
        java.util.Date now = new java.util.Date();
        param.setCreateTime(now);
        Integer added = sysTaskLogService.add(param);
        ResultInfo<String> info = new ResultInfo<>(param.getId());
        return info;
    }

    @ApiOperation("删除任务执行记录")
    @PostMapping("/del")
    public ResultInfo<Integer> del(@RequestParam("ids") List<String> ids) {
        Integer deleted = sysTaskLogService.deleteByIds(ids);
        ResultInfo<Integer> info = new ResultInfo<>(deleted);
        return info;
    }

    @ApiOperation("更新任务执行记录")
    @PostMapping("/edit")
    public ResultInfo<Integer> edit(@ModelAttribute SysTaskLog param) {
        java.util.Date now = new java.util.Date();
        Integer updated = sysTaskLogService.update(param);
        ResultInfo<Integer> info = new ResultInfo<>(updated);
        return info;
    }

    @ApiOperation("查看任务执行记录")
    @GetMapping("/info")
    public ResultInfo<SysTaskLog> info(@RequestParam("id") String id) {
        SysTaskLog info = sysTaskLogService.loadById(id);
        TaskUtil.cleanLogMaxTime(info);
        return new ResultInfo<>(info);
    }

    @ApiOperation("任务执行记录列表")
    @GetMapping("/list")
    public ResultList<SysTaskLog> list(SysTaskLog param, @RequestParam(value = "pageIndex", defaultValue = "1") Integer pageIndex, @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        PageInfo<SysTaskLog> info = sysTaskLogService.list(param, pageIndex, pageSize);
        TaskUtil.cleanLogMaxTime(info.getList());
        return new ResultList<>(info);
    }

    @ApiOperation("查看任务执行日志")
    @GetMapping("/view")
    public void view(@RequestParam("id") String id
            , @RequestParam(value = "down", required = false) String down
            , HttpServletResponse response) throws IOException {
        SysTaskLog info = sysTaskLogService.loadById(id);

        response.setContentType("text/plain");
        response.setCharacterEncoding("UTF-8");

        if (info == null) {
            response.getWriter().write("Not found task " + id + " logs");
            return;
        }

        if ("1".equals(down)) {
            String filename = id + ".log";
            response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(filename, CharsetUtil.getSystemCharset()) + "\"");
        }

        //
        String logPath = info.getLogPath();
        if (!StringUtils.hasText(logPath)) {
            response.getWriter().write("NoLog");
        } else if (logPath.startsWith("file://")) {
            String filePath = logPath.substring("file://".length()).replace("\\", "/");
            try (FileInputStream stream = new FileInputStream(filePath)) {
                IOUtils.copy(stream, response.getWriter(), "UTF-8");
            }
        } else if (logPath.startsWith("storage://")) {
            String storagePath = logPath.substring("storage://".length()).replace("\\", "/");
            try (InputStream stream = this.fileStorage.getStream(storagePath)) {
                IOUtils.copy(stream, response.getWriter(), "UTF-8");
            }
        } else if (logPath.startsWith("db://")) {
            String runId = logPath.substring("db://".length());
            SysTaskDetail detail = this.sysTaskDetailService.loadById(runId);
            if (detail == null) {
                response.getWriter().write("Not found task " + id + " logs");
                return;
            }
            response.getWriter().write(detail.getDetail());
        } else {
            response.getWriter().write("Log path invalid, Not open " + logPath);
        }
    }
}